/**
 * Copyright (c) 2012-2016, www.tinygroup.org (luo_guo@icloud.com).
 *
 *  Licensed under the GPL, Version 3.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.gnu.org/licenses/gpl.html
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.tinygroup.bizframe.processors;

import java.util.ArrayList;
import java.util.List;

import org.tinygroup.application.Application;
import org.tinygroup.application.ApplicationProcessor;
import org.tinygroup.beancontainer.BeanContainerFactory;
import org.tinygroup.bizframe.common.util.BeanUtil;
import org.tinygroup.bizframe.service.inter.SysMenuService;
import org.tinygroup.bizframe.service.inter.dto.SysMenuDto;
import org.tinygroup.config.impl.AbstractConfiguration;
import org.tinygroup.config.util.ConfigurationUtil;
import org.tinygroup.fileresolver.FileResolver;
import org.tinygroup.logger.LogLevel;
import org.tinygroup.menuframe.config.Menu;
import org.tinygroup.menuframe.manager.MenuTreeManager;
import org.tinygroup.xmlparser.node.XmlNode;

public class SysMenuMonitorProcessor extends AbstractConfiguration implements
        ApplicationProcessor {

    private static final String SYS_MENU_MONITOR_NODE_PATH = "/application/sysmenu-monitor";
    private static final int DEFAULT_INTERVAL = 5;
    private SysMenuMonitorThread thread = null;
    private int interval = DEFAULT_INTERVAL;
    private boolean enable = false;
    private SysMenuService sysMenuService;
    
    private MenuTreeManager menuTreeManager;
    
    
    private byte[] synObject = new byte[0];

    

    public String getApplicationNodePath() {
        return SYS_MENU_MONITOR_NODE_PATH;
    }

    public String getComponentConfigPath() {
        return "/sysMenuMonitor.config.xml";
    }

    public void start() {
        XmlNode combineNode = ConfigurationUtil.combineXmlNode(
                applicationConfig, componentConfig);
        if (combineNode != null) {
            String strInterrupt = combineNode.getAttribute("interval");
            if (strInterrupt != null && strInterrupt.length() > 0) {
                interval = Integer.parseInt(strInterrupt);
            }
            String enableString = combineNode.getAttribute("enable");
            if (enableString != null && enableString.length() > 0) {
                enable = Boolean.valueOf(enableString);
            }
        }

        if (enable) {
            if (thread != null) {
                thread.stop = true;
            }
            thread = new SysMenuMonitorThread();
            thread.setDaemon(true);
            thread.start();
        }

    }

    public void stop() {
        synchronized (synObject) {
            if (enable && thread != null && thread.isAlive()) {
                thread.stop = true;
                synObject.notify();// 唤醒其他等待的线程
            }
        }
    }

    public void setApplication(Application application) {
        //do nothing
    }

    public int getOrder() {
        return DEFAULT_PRECEDENCE;
    }

    public void init() {
        // TODO Auto-generated method stub

    }

    public SysMenuService getSysMenuService() {
		return sysMenuService;
	}

	public void setSysMenuService(SysMenuService sysMenuService) {
		this.sysMenuService = sysMenuService;
	}

	public MenuTreeManager getMenuTreeManager() {
		return menuTreeManager;
	}

	public void setMenuTreeManager(MenuTreeManager menuTreeManager) {
		this.menuTreeManager = menuTreeManager;
	}

	private class SysMenuMonitorThread extends Thread {
        private static final int MILLISECOND_PER_SECOND = 1000;
        private volatile boolean stop = false;

        public void run() {
            while (!stop) {
                try {
                    synchronized (synObject) {
                        if (!stop) {// 唤醒时，或者等待时间后，发现stop=false时去执行重新搜索。
                            LOGGER.logMessage(LogLevel.INFO, "定时扫描系统菜单变化......");
                            sysMenuService = BeanContainerFactory.getBeanContainer(this.getClass().getClassLoader())
                            		.getBean("sysMenuServiceImpl");
                            
                            menuTreeManager=BeanContainerFactory.getBeanContainer(this.getClass().getClassLoader())
                            		.getBean("menuTreeManager");
                            
                            if(sysMenuService == null || menuTreeManager == null){
                            	LOGGER.logMessage(LogLevel.WARN, "sysMenuService 不存在?{0},或者menuTreeManager不存在?{1}"
                            			,sysMenuService == null?"Y":"N"
                            				,menuTreeManager == null?"Y":"N");
                            	return;
                            }
                            List<SysMenuDto> allMenuList = sysMenuService.getSysMenuList(null);
                            List<Menu> menuList = new ArrayList<Menu>();
                            for(SysMenuDto sysMenuDto:allMenuList){
                                Menu menu = BeanUtil.copyProperties(Menu.class,sysMenuDto);
                                menu.setId(sysMenuDto.getMenuId());
                                menu.setUrl(sysMenuDto.getMenuUrl());
                                menu.setMenuIcon(sysMenuDto.getMenuIcon());
                                menuList.add(menu);
                            }
                            
                            menuTreeManager.load(menuList);
                            LOGGER.logMessage(LogLevel.INFO, "定时扫描系统菜单变化结束.");
                        }
                        synObject.wait(interval * MILLISECOND_PER_SECOND);// 没有线程唤醒，那么等待这么多时间
                    }
                } catch (InterruptedException e) {
                    LOGGER.errorMessage(e.getMessage(), e);
                }
            }
        }
    }
}
